<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>boom bam beat</title>
<link type="text/css" href="bbb/boombambeat.css" rel="stylesheet" />
<script type="text/javascript" src="libs/DAT.GUI.min.js"></script>
<script type="text/javascript" src="tdl/base.js"></script>
<script type="text/javascript" src="bbb/main.js"></script>
</head>
<body>
<div class="fpsContainer">
  <div class="fps">fps: <span id="fps"></div>
</div>
<div id="viewContainer">
<canvas id="canvas" width="1024" height="1024" style="width: 100%; height: 100%;"></canvas>
</div>
</body>
<!-- ===========================================================================

phong shader

============================================================================ -->
<script id="phongVertexShader" type="text/something-not-javascript">
uniform mat4 worldViewProjection;
uniform vec3 lightWorldPos;
uniform mat4 world;
uniform mat4 viewInverse;
uniform mat4 worldInverseTranspose;
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;
void main() {
  v_texCoord = texCoord;
  v_position = (worldViewProjection * position);
  v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz;
  v_surfaceToLight = lightWorldPos - (world * position).xyz;
  v_surfaceToView = (viewInverse[3] - (world * position)).xyz;
  gl_Position = v_position;
}

</script>
<script id="phongFragmentShader" type="text/something-not-javascript">
#ifdef GL_ES
precision highp float;
#endif
uniform vec4 lightColor;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;

uniform sampler2D diffuseSampler;
uniform vec4 specular;
uniform sampler2D bumpSampler;
uniform float shininess;
uniform float specularFactor;

vec4 lit(float l ,float h, float m) {
  return vec4(1.0,
              max(l, 0.0),
              (l > 0.0) ? pow(max(0.0, h), m) : 0.0,
              1.0);
}
void main() {
  vec4 diffuse = texture2D(diffuseSampler, v_texCoord);
  vec3 normal = normalize(v_normal);
  vec3 surfaceToLight = normalize(v_surfaceToLight);
  vec3 surfaceToView = normalize(v_surfaceToView);
  vec3 halfVector = normalize(surfaceToLight + surfaceToView);
  vec4 litR = lit(dot(normal, surfaceToLight),
                    dot(normal, halfVector), shininess);
  gl_FragColor = vec4((
  lightColor * (diffuse * litR.y
                        + specular * litR.z * specularFactor)).rgb,
      diffuse.a);
}
</script>
<!-- ===========================================================================

repeat shader

============================================================================ -->
<script id="repeatVertexShader" type="text/something-not-javascript">
uniform mat4 viewProjection;
uniform vec3 lightWorldPos;
uniform mat4 world;
uniform mat4 viewInverse;
uniform sampler2D offsetTexture;
uniform vec4 offsetScale;

attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
attribute vec4 extra;

varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec4 v_color;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;

const float kOffsetTextureHeight = 4.0;
const float kPixelOffset = 1.0 / kOffsetTextureHeight;
const float kHalfPixelOffset = kPixelOffset / 2.0;
const float kOffsetXYZSLow = kHalfPixelOffset;
const float kOffsetXYZSHigh = kHalfPixelOffset + kPixelOffset;
const float kOffsetColor = kHalfPixelOffset + kPixelOffset * 2.0;
const float kOffsetRotation = kHalfPixelOffset + kPixelOffset * 3.0;

mat4 quatToMatrix(vec4 orientation, vec3 translation) {
  vec4 q2 = orientation + orientation;
  vec4 qx = orientation.xxxw * q2.xyzx;
  vec4 qy = orientation.xyyw * q2.xyzy;
  vec4 qz = orientation.xxzw * q2.xxzz;

  return mat4(
      (1.0 - qy.y) - qz.z,
      qx.y + qz.w,
      qx.z - qy.w,
      0,

      qx.y - qz.w,
      (1.0 - qx.x) - qz.z,
      qy.z + qx.w,
      0,

      qx.z + qy.w,
      qy.z - qx.w,
      (1.0 - qx.x) - qy.y,
      0,

      translation.x, translation.y, translation.z, 1);
}

void main() {

  vec4 xyzsLowOff = texture2D(offsetTexture, vec2(extra.x, kOffsetXYZSLow));
  vec4 xyzsHighOff = texture2D(offsetTexture, vec2(extra.x, kOffsetXYZSHigh));
  vec4 color = texture2D(offsetTexture, vec2(extra.x, kOffsetColor));
  vec4 rotation =
      texture2D(offsetTexture, vec2(extra.x, kOffsetRotation)) * 2.0 -
      vec4(1, 1, 1, 1);

  vec4 xyzsOffset = vec4(xyzsLowOff * 256.0 + xyzsHighOff * 65536.0) / 65535.0 *
      offsetScale - offsetScale * 0.5;

  mat4 local = world * quatToMatrix(rotation, xyzsOffset.xyz);
  mat4 worldViewProjection = viewProjection * local;

  v_color = color;
  v_texCoord = texCoord;
  v_position = worldViewProjection * position;
  v_normal = (world * vec4(normal, 0)).xyz;
  v_surfaceToLight = lightWorldPos - (local * position).xyz;
  v_surfaceToView = (viewInverse[3] - (local * position)).xyz;
  gl_Position = v_position;
}

</script>
<script id="repeatFragmentShader" type="text/something-not-javascript">
#ifdef GL_ES
precision highp float;
#endif
uniform vec4 lightColor;
varying vec4 v_color;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;

uniform sampler2D diffuseSampler;
uniform vec4 specular;
uniform sampler2D bumpSampler;
uniform float shininess;
uniform float specularFactor;

vec4 lit(float l ,float h, float m) {
  return vec4(1.0,
              max(l, 0.0),
              (l > 0.0) ? pow(max(0.0, h), m) : 0.0,
              1.0);
}
void main() {
  //vec4 diffuse = texture2D(diffuseSampler, v_texCoord);
  vec4 diffuse = v_color;
  vec3 normal = normalize(v_normal);
  vec3 surfaceToLight = normalize(v_surfaceToLight);
  vec3 surfaceToView = normalize(v_surfaceToView);
  vec3 halfVector = normalize(surfaceToLight + surfaceToView);
  vec4 litR = lit(dot(normal, surfaceToLight),
                    dot(normal, halfVector), shininess);
  gl_FragColor = vec4((
  lightColor * (diffuse * litR.y
                        + specular * litR.z * specularFactor)).rgb,
      diffuse.a);
}
</script>
<!-- ===========================================================================

spiro shader

============================================================================ -->
<script id="spiroVertexShader" type="text/something-not-javascript">
uniform mat4 viewProjection;
uniform vec3 lightWorldPos;
uniform mat4 world;
uniform mat4 viewInverse;

uniform float time;
uniform sampler2D segmentTexture;
uniform float modelsPerSegment;
uniform vec4 segmentScale;
uniform float segmentSpacingZ;
uniform vec2 segmentMoveScale;
uniform vec2 segmentMovePhase;
uniform vec2 texCoordOffset;

attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
// Data in extra: x = 1/modelNum, modelNum, 0, 0
attribute vec4 extra;

varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec4 v_color;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;

const float kSegmentTextureHeight = 4.0;
const float kPixelOffset = 1.0 / kSegmentTextureHeight;
const float kHalfPixelOffset = kPixelOffset / 2.0;
const float kOffsetXYZSLow = kHalfPixelOffset;
const float kOffsetXYZSHigh = kHalfPixelOffset + kPixelOffset;
const float kOffsetColor = kHalfPixelOffset + kPixelOffset * 2.0;
const float kOffsetRotation = kHalfPixelOffset + kPixelOffset * 3.0;

mat4 quatToMatrix(vec4 orientation, vec3 translation) {
  vec4 q2 = orientation + orientation;
  vec4 qx = orientation.xxxw * q2.xyzx;
  vec4 qy = orientation.xyyw * q2.xyzy;
  vec4 qz = orientation.xxzw * q2.xxzz;

  return mat4(
      (1.0 - qy.y) - qz.z,
      qx.y + qz.w,
      qx.z - qy.w,
      0,

      qx.y - qz.w,
      (1.0 - qx.x) - qz.z,
      qy.z + qx.w,
      0,

      qx.z + qy.w,
      qy.z - qx.w,
      (1.0 - qx.x) - qy.y,
      0,

      translation.x, translation.y, translation.z, 1);
}

void main() {
  float halfPixelWidth = 0.5 / modelsPerSegment;
  float modelId       = extra.y;
  float segmentUnitId = floor(mod(modelId, modelsPerSegment));
  float segmentId     = floor(modelId / modelsPerSegment);
  float unitPixel     = segmentUnitId / modelsPerSegment + halfPixelWidth;

  vec4 xyzsLowOff = texture2D(segmentTexture, vec2(unitPixel, kOffsetXYZSLow));
  vec4 xyzsHighOff = texture2D(segmentTexture, vec2(unitPixel, kOffsetXYZSHigh));
  vec4 color = texture2D(segmentTexture, vec2(unitPixel, kOffsetColor));
  vec4 rotation =
      texture2D(segmentTexture, vec2(unitPixel, kOffsetRotation)) * 2.0 -
      vec4(1, 1, 1, 1);

  vec2 segmentClock = time + segmentId * segmentMovePhase;
  vec2 segmentMovement = vec2(sin(segmentClock.x), cos(segmentClock.y)) *
      segmentMoveScale;

  vec4 xyzsOffset = vec4(xyzsLowOff * 256.0 + xyzsHighOff * 65536.0) / 65535.0 *
      segmentScale - segmentScale * 0.5 +
      vec4(segmentMovement, segmentId * segmentSpacingZ, 0);

  mat4 local = world * quatToMatrix(rotation, xyzsOffset.xyz);
  mat4 worldViewProjection = viewProjection * local;

  v_color = color;
  v_texCoord = texCoord + texCoordOffset;
  v_position = worldViewProjection * position;
  v_normal = (world * vec4(normal, 0)).xyz;
  v_surfaceToLight = lightWorldPos - (local * position).xyz;
  v_surfaceToView = (viewInverse[3] - (local * position)).xyz;
  gl_Position = v_position;
}

</script>
<script id="spiroFragmentShader" type="text/something-not-javascript">
#ifdef GL_ES
precision highp float;
#endif
uniform vec4 lightColor;
varying vec4 v_color;
varying vec4 v_position;
varying vec2 v_texCoord;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
varying vec3 v_surfaceToView;

uniform sampler2D colorSampler;
uniform vec4 specular;
uniform sampler2D bumpSampler;
uniform float shininess;
uniform float specularFactor;

vec4 lit(float l ,float h, float m) {
  return vec4(1.0,
              max(l, 0.0),
              (l > 0.0) ? pow(max(0.0, h), m) : 0.0,
              1.0);
}
void main() {
  vec4 colorMult = texture2D(colorSampler, v_texCoord);
  vec4 diffuse = v_color;
  vec3 normal = normalize(v_normal);
  vec3 surfaceToLight = normalize(v_surfaceToLight);
  vec3 surfaceToView = normalize(v_surfaceToView);
  vec3 halfVector = normalize(surfaceToLight + surfaceToView);
  vec4 litR = lit(dot(normal, surfaceToLight),
                    dot(normal, halfVector), shininess);
  gl_FragColor = vec4((
  lightColor * (diffuse * litR.y
                        + specular * litR.z * specularFactor)).rgb,
      diffuse.a) + colorMult;
}
</script>
</html>

